/**
 * Framework for batch testing user profile models
 * Final project by Sergey Nepomnyachiy and Julia Polchin
 * Supervisor: Tsvi Kuflik
 *
 */
package core;

import interfaces.ComponentInterface;
import interfaces.LoggingInterface;
import interfaces.ProgressKeeperInterface;

import java.util.Collection;
import java.util.Vector;

import backend.DummyProgKeeper;
import backend.Stats;

/**
 * Class representing the Study element in XML
 * @author Sergey and Julia
 * 
 */
public class Study implements ComponentInterface {
	/**
	 * Groups of the study
	 */
	private Vector<Group> groups;
	/**
	 * Steps of the study
	 */
	private Vector<Step> steps;
	/**
	 * Both of them
	 */
	private Vector<ComponentInterface> stepsAndGroups;
   /**
    * Logging backend
    */
	private LoggingInterface fs;
	/**
	 * The name of study (should be valid folder name)
	 */
	private String name;
	/**
	 * Progress keeper
	 */
	@SuppressWarnings("unused")
	private ProgressKeeperInterface pk;

	/**
	 * Constructor for study
	 * @param name Name of the study
	 * @param fs Logging backend
	 */
	public Study(String name, LoggingInterface fs) {
		this.fs = fs;
		this.name = name;
		this.groups = new Vector<Group>();
		this.steps = new Vector<Step>();
		this.stepsAndGroups = new Vector<ComponentInterface>();
		this.pk = new DummyProgKeeper();
	}

	@Override
	public boolean execute() {
		
		for (ComponentInterface ci : this.stepsAndGroups) {
			ci.execute();
		}
		Collection<Object> observed = StudyObservedPredictedHolder.getInstance().getObserved();
		Collection<Object> predicted =	StudyObservedPredictedHolder.getInstance().getPredicted();
		this.fs.write(this.name + ".s","correlation="+Stats.getCorrelation(observed, predicted)+"\n");
		this.fs.write(this.name + ".s","mae="+Stats.getMAE(observed, predicted)+"\n");
		StudyObservedPredictedHolder.getInstance().clear();
		
		return true;
	}

	@Override
	public void setFs(LoggingInterface fs) {
		this.fs = fs;
		for (ComponentInterface ci : this.stepsAndGroups) 
			ci.setFs(fs);

	}

	/**
	 * Adding new group to study
	 * @param g group to add
	 */
	public void addGroup(Group g) {
		g.setFs(this.fs);
		this.groups.add(g);
		this.stepsAndGroups.add(g);
	}

	/**
	 * Adding new step to study
	 * @param s step to add
	 */
	public void addStep(Step s) {
		this.steps.add(s);
		this.stepsAndGroups.add(s);
	}

	/**
	 * Getter for the name of study
	 * 
	 * @return the name of the study
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * Getter for groups
	 * @return collection of groups
	 */
	public Collection<Group> getGroups() {
		return this.groups;
	}

	@Override
	public void setProgresser(ProgressKeeperInterface pk) {
		this.pk = pk;
		for (Group g : this.groups)
			g.setProgresser(pk);
		
	}
}